package websocket

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"log"
	"strings"
	"tuiwen-go/internal/api"
	"tuiwen-go/internal/db"
	"tuiwen-go/internal/utils"
)

// AudioTaskPayload 定义音频任务消息的结构。
type AudioTaskPayload struct {
	ProjectID string  `json:"project_id"`
	Id        string  `json:"id"`
	Duration  float64 `json:"duration"`
}

// taskAudioHandler handles messages of type 3.
// taskAudioHandler 处理类型为 3 的消息。
func taskAudioHandler(c *Client, data json.RawMessage) {
	log.Printf("客户端 %s: 正在处理音频任务, 数据: %s", c.ID, string(data))

	var payload AudioTaskPayload
	if err := json.Unmarshal(data, &payload); err != nil {
		log.Printf("客户端 %s: 解析音频任务负载错误: %v", c.ID, err)
		sendMessage(c, api.WxJSONResponse{Code: -1, Msg: fmt.Sprintf("数据解析失败: %v", err)})
		return
	}
	sqlQuery := "SELECT id, content, audio,role_ids FROM text WHERE project_id = ? AND content IS NOT NULL"
	args := []interface{}{payload.ProjectID}
	if payload.Id != "" {
		sqlQuery += " AND id = ?"
		args = append(args, payload.Id)
	} else {
		sqlQuery += " and (audio is null or audio ='')"
	}
	rows, err := db.Query(sqlQuery, args...)
	if err != nil {
		log.Printf("客户端 %s: 查询项目 %s的文本错误: %v", c.ID, payload.ProjectID, err)
		sendMessage(c, api.WxJSONResponse{Code: -1, Msg: fmt.Sprintf("查询文本失败: %v", err)})
		return
	}
	defer rows.Close()

	// Define the output directory for audio files
	// 定义音频文件的输出目录
	outputDir := "./public/audio"

	var textsToProcess []struct {
		ID       int
		Content  string
		Audio    string
		Role_ids string
	}

	for rows.Next() {
		var id int
		var content string
		var audio sql.NullString
		var role_ids sql.NullString
		if err := rows.Scan(&id, &content, &audio, &role_ids); err != nil {
			log.Printf("客户端 %s: 扫描文本行错误: %v", c.ID, err)
			continue // Skip this row
		}
		textsToProcess = append(textsToProcess, struct {
			ID       int
			Content  string
			Audio    string
			Role_ids string
		}{ID: id, Content: content, Audio: audio.String, Role_ids: role_ids.String})
	}

	if err = rows.Err(); err != nil {
		log.Printf("客户端 %s: 遍历文本行错误: %v", c.ID, err)
		sendMessage(c, api.WxJSONResponse{Code: -1, Msg: fmt.Sprintf("处理文本失败: %v", err)})
		return
	}

	// Process each text to generate audio
	// 处理每个文本以生成音频
	for _, textData := range textsToProcess {
		log.Printf("客户端 %s: 正在为文本 ID %d 生成音频", c.ID, textData.ID)

		// 如果存在旧音频文件，则删除它
		if textData.Audio != "" {
			oldAudioPath := outputDir + textData.Audio[len("/public/audio"):]
			log.Printf("客户端 %s: 正在删除旧音频文件: %s", c.ID, oldAudioPath)
			err := utils.DeleteFile(oldAudioPath)
			if err != nil {
				log.Printf("客户端 %s: 删除旧音频文件 %s 失败: %v", c.ID, oldAudioPath, err)
			}
		}
		var voice = ""
		if textData.Role_ids != "" {
			role_ids := strings.Split(textData.Role_ids, ",")
			if len(role_ids) > 0 {
				err := db.QueryRow("SELECT sound FROM role WHERE id = ?", role_ids[0]).Scan(&voice)
				if err != nil {
					log.Printf("客户端 %s: 查询角色 %s 声音错误: %v", c.ID, role_ids[0], err)
				}
			}
		}

		// Generate audio using edge-tts
		// 使用 edge-tts 生成音频
		audioPath, err := utils.GenerateAudioWithEdgeTTS(textData.Content, voice, outputDir)
		if err != nil {
			log.Printf("客户端 %s: 为文本 ID %d 生成音频错误: %v", c.ID, textData.ID, err)
			// Continue to the next text even if one fails
			sendMessage(c, api.WxJSONResponse{Code: -1, Msg: fmt.Sprintf("文本 ID %d 音频生成失败: %v", textData.ID, err), Data: map[string]interface{}{"text_id": textData.ID}})
			continue
		}
		audioPath = "/" + strings.ReplaceAll(audioPath, "\\", "/")

		// 获取音频时长
		duration, err := utils.GetAudioDuration("." + audioPath)
		if err != nil {
			log.Printf("客户端 %s: 获取文本 ID %d 音频时长错误: %v", c.ID, textData.ID, err)
			sendMessage(c, api.WxJSONResponse{Code: -1, Msg: fmt.Sprintf("文本 ID %d 音频时长获取失败: %v", textData.ID, err), Data: map[string]interface{}{"text_id": textData.ID}})
			continue
		}

		// Update the database with the audio file path and duration
		// 更新数据库中的音频文件路径和时长
		_, err = db.Exec("UPDATE text SET audio = ?, audio_duration = ? WHERE id = ?", audioPath, duration, textData.ID)
		if err != nil {
			log.Printf("客户端 %s: 更新文本 ID %d 的音频路径和时长错误: %v", c.ID, textData.ID, err)
			// Continue to the next text even if one fails
			sendMessage(c, api.WxJSONResponse{Code: -1, Msg: fmt.Sprintf("文本 ID %d 数据库更新失败: %v", textData.ID, err), Data: map[string]interface{}{"text_id": textData.ID}})
			continue
		}

		log.Printf("客户端 %s: 文本 ID %d 音频生成、保存并获取时长成功: %s, 时长: %.2f秒", c.ID, textData.ID, audioPath, duration)
		// Send a message for each successfully processed text
		sendMessage(c, api.WxJSONResponse{Code: 1, Msg: "文本配音生成成功", Data: map[string]interface{}{"id": textData.ID, "audio_path": audioPath, "duration": duration}})
	}

	log.Printf("客户端 %s: 项目 %s 的所有符合条件的文本音频任务处理完成", c.ID, payload.ProjectID)
	// A final success message after attempting all updates
	// 所有更新尝试后的最终成功消息
	sendMessage(c, api.WxJSONResponse{Code: 0, Msg: "项目配音生成任务完成", Data: map[string]interface{}{"project_id": payload.ProjectID}})
}
